package com.example.camerademo.camerax

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.util.Rational
import android.util.Size
import android.view.OrientationEventListener
import android.view.Surface
import android.view.WindowManager
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.dylanc.viewbinding.inflate
import com.example.camerademo.databinding.ActivityCameraXactivityBinding
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.lifecycle.LifecycleOwner
import com.example.camerademo.camera1.utils.FileUtil
import com.google.common.util.concurrent.ListenableFuture
import java.io.File
import java.util.concurrent.Executor
import java.util.concurrent.TimeUnit

/**
 * Android CameraX实现摄像头预览、拍照、录制视频
 * //https://blog.csdn.net/mq2856992713/article/details/115602968
https://blog.csdn.net/yoonerloop/article/details/107736419

 */

class CameraXActivity : AppCompatActivity() {

    private val binding: ActivityCameraXactivityBinding by inflate()

    private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
    lateinit var camera: Camera;
    lateinit var cameraControl: CameraControl;
    lateinit var cameraExecutor: Executor

    // lateinit var windowManager: WindowManager
    var lensFacing: Int = CameraSelector.LENS_FACING_BACK

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        //Initialize WindowManager to retrieve display metrics
        // windowManager = WindowManager(binding.btnChange.context)

        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraExecutor = ContextCompat.getMainExecutor(this)
        //请求 CameraProvider 后，请验证它能否在视图创建后成功初始化。以下代码展示了如何执行此操作
        cameraProviderFuture.addListener(Runnable {
            val cameraProvider = cameraProviderFuture.get()
            bindPreview(cameraProvider, lensFacing)
        }, cameraExecutor)

        initListener();


    }


    private fun initListener() {

        binding.apply {

            btnFocus.setOnClickListener {
                /*  val factory = SurfaceOrientedMeteringPointFactory(720f, 1280f)
                  val point = factory.createPoint(500f, 500f)
                  val action = FocusMeteringAction.Builder(point, FocusMeteringAction.FLAG_AF)
                      //.addPoint(point2, FocusMeteringAction.FLAG_AE) // could have many
                      // auto calling cancelFocusAndMetering in 5 seconds
                      .setAutoCancelDuration(5, TimeUnit.SECONDS)
                      .build()

                  val future = cameraControl.startFocusAndMetering(action)
                  future.addListener(Runnable {
                      val result = future.get()
                      println("CameraXActivity.initListener result=" + result.isFocusSuccessful)
                  }, cameraExecutor)*/

            }

            btnChange.setOnClickListener {
                //请求 CameraProvider 后，请验证它能否在视图创建后成功初始化。以下代码展示了如何执行此操作
                cameraProviderFuture.addListener(Runnable {

                    if (lensFacing == CameraSelector.LENS_FACING_BACK) {
                        lensFacing = CameraSelector.LENS_FACING_FRONT;
                    } else {
                        lensFacing = CameraSelector.LENS_FACING_BACK;
                    }
                    val cameraProvider = cameraProviderFuture.get()
                    bindPreview(cameraProvider, lensFacing)
                }, cameraExecutor)
            }




            btnTakePic.setOnClickListener {
                // 获取Jpeg图片，并保存在sd卡上
                val path = FileUtil.getCommonSavePath(this@CameraXActivity) + "/a_focus/"
                println(".onPictureTaken path=$path")
                val pathDir = File(path)
                if (!pathDir.exists()) {
                    pathDir.mkdir()
                }

                val filePath = path + System.currentTimeMillis() + ".jpg";
                println("CameraXActivity.initListener filePath=$filePath")
                val pictureFile = File(filePath)
                /*if (pictureFile.exists()) {
                    pictureFile.delete()
                }*/

                val outputFileOptions = ImageCapture.OutputFileOptions
                    .Builder(pictureFile)
                    .build()
                imageCapture.takePicture(outputFileOptions, cameraExecutor,
                    object : ImageCapture.OnImageSavedCallback {
                        override fun onError(error: ImageCaptureException) {
                            println("CameraXActivity.onError")
                        }

                        override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                            println("CameraXActivity.onImageSaved")
                            val savedUri = outputFileResults.savedUri
                            if (savedUri != null) {
                                val fromFile = Uri.fromFile(pictureFile)
                                // img.setImageURI(savedUri)

                                val intent =
                                    Intent(this@CameraXActivity, TakePicActivity::class.java);
                                intent.putExtra("savedUri", savedUri)
                                startActivity(intent)

                            }
                            Toast.makeText(this@CameraXActivity, "拍摄成功", Toast.LENGTH_SHORT).show();
                        }
                    })
            }
        }
    }

    private fun addOrientationEventListener(imageCapture: ImageCapture) {
        val orientationEventListener: OrientationEventListener =
            object : OrientationEventListener(this as Context) {
                override fun onOrientationChanged(orientation: Int) {
                    // Monitors orientation values to determine the target rotation value
                    val rotation: Int = when (orientation) {
                        in 45..134 -> Surface.ROTATION_270
                        in 135..224 -> Surface.ROTATION_180
                        in 225..314 -> Surface.ROTATION_90
                        else -> Surface.ROTATION_0
                    }

                    println("CameraXActivity.onOrientationChanged rotation=$rotation")
                    imageCapture.targetRotation = rotation
                }
            }
        orientationEventListener.enable();
    }


    lateinit var imageCapture: ImageCapture;
    private val TAG = "CameraXActivity"

    @SuppressLint("WrongConstant", "UnsafeOptInUsageError")
    fun bindPreview(cameraProvider: ProcessCameraProvider, lensFacing: Int) {
        // Get screen metrics used to setup camera for full screen resolution
        /*  val metrics = windowManager.getCurrentWindowMetrics().bounds
          Log.d(TAG, "Screen metrics: ${metrics.width()} x ${metrics.height()}")

          val screenAspectRatio = aspectRatio(metrics.width(), metrics.height())
          Log.d(TAG, "Preview aspect ratio: $screenAspectRatio")*/


        var preview: Preview = Preview.Builder()
            .setTargetAspectRatio(AspectRatio.RATIO_4_3)
            //.setTargetResolution(Size(640, 480))
            .build()

        //相机摄像头设置
        var cameraSelector: CameraSelector = CameraSelector.Builder()
            //.requireLensFacing(CameraSelector.LENS_FACING_FRONT)
            .requireLensFacing(lensFacing)
            .build()

        println("CameraXActivity.bindPreview binding.previewView.display.rotation=" + binding.previewView.display.rotation)
        //图像捕捉
        imageCapture = ImageCapture.Builder()
            //优化捕获速度，可能降低图片质量,拍照时：闪光灯会开启
            //.setFlashMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)


            //优化捕获管道以优先考虑图像质量而不是延迟。当捕获模式设置为 MAX_QUALITY 时，捕获图像可能需要更长的时间。
            //拍照时：闪光灯不会开启
            .setFlashMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)

            //设置旋转角度
            //.setTargetRotation(binding.previewView.display.rotation)

            //.setTargetAspectRatio(AspectRatio.RATIO_16_9)

            //设置设置目标分辨率宽高比(不能和setTargetAspectRatio一起使用，二者使其一)
            //.setTargetResolution(Size(640, 480))
            .build()

        //addOrientationEventListener(imageCapture);


        //指定分辨率
        // ImageAnalysis
        val imageAnalyzer = ImageAnalysis.Builder()
            //.setTargetResolution(Size(1280, 720))
            //.setTargetAspectRatio(AspectRatio.RATIO_4_3)
            .setImageQueueDepth(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            //.setTargetRotation(rotation)
            .build()
            .also {
                it.setAnalyzer(ContextCompat.getMainExecutor(this), { image: ImageProxy ->
                    //我们可以从IamgeProxy中拿到每一帧画面的图像数据;
                    println("CameraXActivity.bindPreview setAnalyzer")
                    val buffer = image.planes[0].buffer


                    //一定要调用IamgeProxy.close()方法关闭，否则analyze(ImageProxy image)这个方法只会回调一次
                    image.close()
                })
            }

        /*imageAnalyzer.setAnalyzer(
            ContextCompat.getMainExecutor(this),
            object : ImageAnalysis.Analyzer {
                override fun analyze(image: ImageProxy) {
                    //这里拿到字节数组可以为 所 欲 为 ！
                    val buffer = image.planes[0].buffer
                }

            })*/


        val orientationEventListener = object : OrientationEventListener(this as Context) {
            override fun onOrientationChanged(orientation: Int) {
                // Monitors orientation values to determine the target rotation value
                val rotation: Int = when (orientation) {
                    in 45..134 -> Surface.ROTATION_270
                    in 135..224 -> Surface.ROTATION_180
                    in 225..314 -> Surface.ROTATION_90
                    else -> Surface.ROTATION_0
                }
                imageCapture.targetRotation = rotation
            }
        }
        orientationEventListener.enable()

        preview.setSurfaceProvider(binding.previewView.getSurfaceProvider())

        // 必须在重新绑定用例之前解除绑定它们
        cameraProvider.unbindAll()

        camera = cameraProvider.bindToLifecycle(
            this as LifecycleOwner,
            cameraSelector,
            preview,
            imageCapture,
            imageAnalyzer
        )


        /* var width=720;
         var height=1280;
         //剪裁矩形
         val viewPort =
             ViewPort.Builder(Rational(width, height), binding.previewView.display.rotation).build()
         val useCaseGroup = UseCaseGroup.Builder()
             .addUseCase(preview)
             .addUseCase(imageAnalyzer)
             .addUseCase(imageCapture)
             .setViewPort(viewPort)
             .build()
         camera = cameraProvider.bindToLifecycle(
             this as LifecycleOwner,
             cameraSelector,
             useCaseGroup
         )*/

        cameraControl = camera.getCameraControl()
    }


    private fun startCamera() {

    }

/*
      binding.apply {
            viewFinder.addOnLayoutChangeListener(object : View.OnLayoutChangeListener {
                override fun onLayoutChange(
                    v: View?,
                    left: Int,
                    top: Int,
                    right: Int,
                    bottom: Int,
                    oldLeft: Int,
                    oldTop: Int,
                    oldRight: Int,
                    oldBottom: Int
                ) {



                }
            })

            viewFinder.post { startCamera() }


        }*/

}